from typing import Annotated
from fastapi import APIRouter, Depends
from fastapi.security import OAuth2PasswordRequestForm
from pydantic import BaseModel
from starlette.requests import Request
from starlette.responses import JSONResponse

from src.base.beans import Rest
from src.config.auth import LoginUser, create_access_token, JWT_TOKEN_PREFIX, auth_depend
from src.base.exception import ServerException
from src.config.db import DbSession
from src.config.log import log_depend
from src.dao.sys_menu_dao import get_menu_list_by_user_id
from src.dao.sys_role_dao import get_role_list_by_user_id
from src.dao.sys_user_dao import get_user_by_user_name, get_user_by_id
from src.domain.sys_menu import SysMenu
from src.domain.sys_user import SysUserResp
from src.utils.common_utils import verify_password

router = APIRouter(prefix="/auth", tags=["登录相关"])


class Token(BaseModel):
    access_token: str
    token_type: str


@router.post("/login", status_code=200, summary="index请求", )
async def login(dbSession: DbSession, form_data: Annotated[OAuth2PasswordRequestForm, Depends()], ):
    user_name = form_data.username
    password = form_data.password
    sys_user = await get_user_by_user_name(dbSession, user_name)
    if not sys_user:
        raise ServerException('auth error', '用户不存在')
    if not verify_password(password, sys_user.password):
        raise ServerException('auth error', '密码错误')
    login_user = LoginUser(**sys_user.model_dump())
    access_token = await create_access_token(login_user, dbSession)
    return {"access_token": access_token, "token_type": JWT_TOKEN_PREFIX}


@router.post("/logout", summary="登出", dependencies=[Depends(auth_depend), Depends(log_depend)], )
async def logout():
    return Rest.ok()


@router.get("/get_login_user_info", summary="获取登录用户的信息",
            dependencies=[Depends(auth_depend), Depends(log_depend)],
            response_model=Rest[SysUserResp])
async def get_login_user_info(dbSession: DbSession, request: Request):
    if not hasattr(request.state, "login_user"):
        return JSONResponse(status_code=401, content={"detail": "身份验证失败，请重新登录！！！"},
                            headers={"WWW-Authenticate": "Bearer"})
    user_id = request.state.login_user.user_id
    sys_user = await get_user_by_id(dbSession, user_id)
    roles = await get_role_list_by_user_id(dbSession, user_id)
    user = SysUserResp(**sys_user.model_dump())
    user.roleCodes = [role.role_code for role in roles]
    return Rest.ok(user)


@router.get("/get_auth_roles", summary="获取用户角色", dependencies=[Depends(auth_depend), Depends(log_depend)], )
async def get_auth_roles(dbSession: DbSession, request: Request):
    user_id = request.state.login_user.user_id
    roles = await get_role_list_by_user_id(dbSession, user_id)
    access_roles = [role.role_code for role in roles]
    return Rest.ok(access_roles)


@router.get("/get_auth_codes", summary="获取用户权限码", dependencies=[Depends(auth_depend), Depends(log_depend)], )
async def get_auth_codes(dbSession: DbSession, request: Request):
    user_id = request.state.login_user.user_id
    menus: list[SysMenu] = await get_menu_list_by_user_id(dbSession, user_id)
    access_codes = [menu.perm for menu in menus]
    return Rest.ok(access_codes)
